package com.nineclock.document.service.impl;

import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.nineclock.common.entity.PageResult;
import com.nineclock.common.entity.UserInfo;
import com.nineclock.common.filter.CurrentUserHolder;
import com.nineclock.common.utils.BeanHelper;
import com.nineclock.document.dto.DocFileDto;
import com.nineclock.document.dto.DocFolderDto;
import com.nineclock.document.dto.DocUserCollaborationDTO;
import com.nineclock.document.dto.DocumentDto;
import com.nineclock.document.enums.DocumentPermissionEnum;
import com.nineclock.document.mapper.*;
import com.nineclock.document.pojo.*;
import com.nineclock.document.service.DocFileService;
import com.nineclock.system.dto.SysCompanyUserDTO;
import com.nineclock.system.dto.SysUserDTO;
import com.nineclock.system.feign.SysCompanyUserFeign;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Transactional
public class DocFileServiceImpl implements DocFileService {

    @Autowired
    private DocFolderMapper folderMapper;

    @Autowired
    private DocFileMapper fileMapper;

    @Autowired
    private SysCompanyUserFeign companyUserFeign;

    @Autowired
    private DocCollaborationsMapper collaborationsMapper;

    @Autowired
    private DocFileHistoryMapper fileHistoryMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Override
    public DocumentDto queryFolderAndFile(Long parentFoldId) {

        // 查询符合条件的文件夹列表
        List<DocFolderDto> folders = queryFolders(parentFoldId);

        // 查询符合条件的文件列表
        List<DocFileDto> files = queryFiles(parentFoldId);

        // 封装数据
        DocumentDto documentDto = new DocumentDto();
        documentDto.setFiles(files);
        documentDto.setFolders(folders);

        return documentDto;
    }


    /**
     * 查询符合条件的文件列表
     * @param parentFoldId
     * @return
     */
    private List<DocFileDto> queryFiles(Long parentFoldId) {

        List<DocFile> fileList = new ArrayList<>();

        // 1.当前目录下，公共读/公共读写 的文件
        LambdaQueryWrapper<DocFile> wrapper1 = new LambdaQueryWrapper<>();
        wrapper1.eq(DocFile::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper1.eq(DocFile::getFolderId, parentFoldId);
        wrapper1.eq(DocFile::getStatus, 1);
        wrapper1.in(DocFile::getPermission, DocumentPermissionEnum.ALL_READ.getPermission(),
                DocumentPermissionEnum.ALL_READ_WRITE.getPermission());

        List<DocFile> fileList1 = fileMapper.selectList(wrapper1);
        if (!CollectionUtils.isEmpty(fileList1)) {
            fileList.addAll(fileList1);
        }

        // B.当前目录下，当前用户私有的文件
        LambdaQueryWrapper<DocFile> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(DocFile::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper2.eq(DocFile::getFolderId, parentFoldId);
        wrapper2.eq(DocFile::getStatus, 1);
        wrapper2.eq(DocFile::getPermission, DocumentPermissionEnum.PRIVATE_READ_WRITE.getPermission());
        // 创建人id等于当前登录用户的员工id
        wrapper2.eq(DocFile::getCreateUserId, CurrentUserHolder.get().getCompanyUserId());

        List<DocFile> fileList2 = fileMapper.selectList(wrapper2);
        if (!CollectionUtils.isEmpty(fileList2)) {
            fileList.addAll(fileList2);
        }


        // C.当前目录下，当前用户是协作者的文件
        List<DocFile> fileList3 = fileMapper.selectFileListByCollaboration(CurrentUserHolder.get().getCompanyId(),
                parentFoldId, CurrentUserHolder.get().getCompanyUserId());

        if (!CollectionUtils.isEmpty(fileList3)) {
            fileList.addAll(fileList3);
        }

        // 文件去重，例如某些文件既是公共读，当前用户又是协作者
        HashSet<DocFile> fileHashSet = new HashSet<>(fileList);

        // 数据转换
        Set<DocFileDto> docFileDtos = BeanHelper.copyWithCollection(fileHashSet, DocFileDto.class);

        List<DocFileDto> docFileDtoList = docFileDtos.stream().map(docFileDto -> {

            // 调用系统微服务Feign接口根据更新人员工id，查询更新人员工信息
            SysCompanyUserDTO updateUserDTO = companyUserFeign.queryCompanyUserById(docFileDto.getUpdateUserId()).getData();
            if (updateUserDTO != null) {
                docFileDto.setUpdateUserName(updateUserDTO.getUserName());
            }

            // 调用系统微服务Feign接口根据创建人员工id，查询创建人员工信息
            SysCompanyUserDTO createUserDTO = companyUserFeign.queryCompanyUserById(docFileDto.getCreateUserId()).getData();
            if (createUserDTO != null) {
                docFileDto.setUserName(createUserDTO.getUserName());
            }

            return docFileDto;

        }).collect(Collectors.toList());

        return docFileDtoList;

    }

    /**
     * 查询符合条件的文件夹列表
     * @return
     */
    private List<DocFolderDto> queryFolders(Long parentFoldId) {
        LambdaQueryWrapper<DocFolder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocFolder::getCompanyId, CurrentUserHolder.get().getCompanyId());
        wrapper.eq(DocFolder::getParentId, parentFoldId);
        wrapper.eq(DocFolder::getStatus, 1);

        List<DocFolder> docFolders = folderMapper.selectList(wrapper);

        if (!CollectionUtils.isEmpty(docFolders)) {
            return BeanHelper.copyWithCollection(docFolders, DocFolderDto.class);
        }
        return null;
    }

    @Override
    public DocFileDto getFileByFileId(Long id) {
        DocFile docFile = fileMapper.selectById(id);
        return BeanHelper.copyProperties(docFile, DocFileDto.class);
    }

    @Override
    public List<DocUserCollaborationDTO> queryUsers(Long id) {

        // 调用系统微服务查询当前企业员工列表
        List<SysCompanyUserDTO> companyUserDTOS = companyUserFeign.queryAllCompanyUser().getData();

        // 根据文件id查询文件
        DocFile docFile = fileMapper.selectById(id);

        // 根据文件id查询协作者id集合
        LambdaQueryWrapper<DocCollaborations> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DocCollaborations::getFileId, id);
        List<DocCollaborations> collaborationsList = collaborationsMapper.selectList(wrapper);

        // 获取协作者id集合
        List<Long> companyUserIdList = collaborationsList.stream().map(docCollaborations -> {
            return docCollaborations.getCollaborationId();
        }).collect(Collectors.toList());


        // 数据转换，将员工DTO转为DocUserCollaborationDTO
        List<DocUserCollaborationDTO> docUserCollaborationDTOS = companyUserDTOS.stream().map(sysCompanyUserDTO -> {

            DocUserCollaborationDTO docUserCollaborationDTO = new DocUserCollaborationDTO();
            docUserCollaborationDTO.setId(sysCompanyUserDTO.getId());
            docUserCollaborationDTO.setUsername(sysCompanyUserDTO.getUserName());
            docUserCollaborationDTO.setImgUrl(sysCompanyUserDTO.getImageUrl());
            docUserCollaborationDTO.setPhone(sysCompanyUserDTO.getMobile());

            if(docFile.getCreateUserId() == sysCompanyUserDTO.getId()){
                docUserCollaborationDTO.setState(1); // 拥有者
            }else if(companyUserIdList.contains(sysCompanyUserDTO.getId())){
                docUserCollaborationDTO.setState(2); // 协作者
            }else{
                docUserCollaborationDTO.setState(0);
            }

            return docUserCollaborationDTO;

        }).collect(Collectors.toList());

        return docUserCollaborationDTOS;
    }

    /**
     * 封禁/解封文件
     * 接口路径：PUT/document/{fileId}/{status}*/
    @Override
    public void updateStatus(Long fileId, Short status) {
        //修改status状态
        DocFile docFile = new DocFile();
        docFile.setId(fileId);
        docFile.setCompanyId(CurrentUserHolder.get().getCompanyId());
        docFile.setUpdateTime(new Date());
        docFile.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
        docFile.setStatus(status);
        fileMapper.updateById(docFile);
    }

    /**
     * 分页查询文件列表
     * 接口路径：GET/document/pagingFile*/
    @Override
    public PageResult<DocFileDto> selectDocFile(String keyword, Integer page, Integer pageSize) {
        LambdaQueryWrapper<DocFile> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(DocFile::getCompanyId,CurrentUserHolder.get().getCompanyId());
        if(!StringUtils.isEmpty(keyword)){
            wrapper.like(DocFile::getName,keyword);
        }
        // 创建分页对象
        IPage<DocFile> ipage = new Page<>(page, pageSize);
        // 执行分页查询
        ipage=fileMapper.selectPage(ipage,wrapper);
        //获取当业的功能
        List<DocFile> docFiles = ipage.getRecords();

        if(!CollectionUtils.isEmpty(docFiles)){
            List<DocFileDto> collect = docFiles.stream().map(docFile -> {
                SysCompanyUserDTO data = companyUserFeign.queryCompanyUserById(docFile.getCreateUserId()).getData();
                LambdaQueryWrapper<DocCollaborations> wrapperq=new LambdaQueryWrapper<>();
                wrapperq.eq(DocCollaborations::getFileId,docFile.getId());
                List<DocCollaborations> docCollaborations = collaborationsMapper.selectList(wrapperq);
                List<SysCompanyUserDTO> collect1 = docCollaborations.stream().map(docCollaborationsa -> {
                    Long collaborationId = docCollaborationsa.getCollaborationId();
                    SysCompanyUserDTO data1 = companyUserFeign.queryCompanyUserById(collaborationId).getData();
                    return data1;
                }).collect(Collectors.toList());
                DocFileDto docFileDto = new DocFileDto();
                docFileDto.setId(docFile.getId());
                docFileDto.setFolderId(docFile.getFolderId());
                docFileDto.setName(docFile.getName());
                docFileDto.setFilePath(docFile.getFilePath());
                docFileDto.setFileSize(docFile.getFileSize());
                docFileDto.setStatus(docFile.getStatus());
                docFileDto.setPermission(docFile.getPermission());
                docFileDto.setType(docFile.getType());
                docFileDto.setCompanyId(docFile.getCompanyId());
                docFileDto.setCreateUserId(docFile.getCreateUserId());
                docFileDto.setCreateTime(docFile.getCreateTime());
                docFileDto.setUpdateUserId(docFile.getUpdateUserId());
                docFileDto.setUpdateTime(docFile.getUpdateTime());
                docFileDto.setCreator(data);
                docFileDto.setUserName(docFile.getName());
                docFileDto.setCollaborations(collect1);
                return docFileDto;
            }).collect(Collectors.toList());
            return new PageResult<DocFileDto>(ipage.getTotal(), ipage.getPages(), collect);
        }
        return new PageResult<DocFileDto>(ipage.getTotal(), ipage.getPages(),null);
    }

    //2021.12.29
    /**
     * 新增文件
     */
    @Override
    public void insertFile(DocFileDto fileDto) {
        //给file表新增文件
        DocFile file = new DocFile();
        file.setFolderId(fileDto.getFolderId());
        file.setName(fileDto.getName());
        file.setFilePath(fileDto.getFilePath());
        file.setFileSize(fileDto.getContent().length()+"B");
        file.setStatus((short)1);
        file.setContent(fileDto.getContent());
        file.setPermission((short)2);
        file.setType((short)1);
        file.setCompanyId(CurrentUserHolder.get().getCompanyId());
        file.setCreateUserId(CurrentUserHolder.get().getCompanyUserId());
        file.setCreateTime(new Date());
        file.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
        file.setUpdateTime(new Date());
        fileMapper.insert(file);

        //给文件历史记录表添加记录
        DocFileHistory fileHistory = new DocFileHistory();
        fileHistory.setFileId(file.getId());
        fileHistory.setFileName(file.getName());
        fileHistory.setOperateUserId(CurrentUserHolder.get().getCompanyUserId());
        fileHistory.setOperateTime(new Date());
        fileHistory.setIsCreate((short)1);
        fileHistory.setContent(file.getContent());
        fileHistoryMapper.insert(fileHistory);


    }

    /**
     * 更新文件
     * @param fileDto
     */
    @Override
    public void updateFile(DocFileDto fileDto) {

        LambdaQueryWrapper<DocFile> wrapper = new LambdaQueryWrapper<>();
        if(fileDto.getId()==null){
            wrapper.eq(DocFile::getName,fileDto.getName());
        }else{
            wrapper.eq(DocFile::getId,fileDto.getId());
        }
        wrapper.eq(DocFile::getFilePath,fileDto.getFilePath());
        wrapper.eq(DocFile::getFolderId,fileDto.getFolderId());
        DocFile docFile = fileMapper.selectOne(wrapper);
        if(docFile!=null){
            DocFile file = new DocFile();
            file.setFolderId(fileDto.getFolderId());
            file.setName(fileDto.getName());
            file.setFilePath(fileDto.getFilePath());
            file.setFileSize(fileDto.getContent().length()+"B");
            file.setContent(fileDto.getContent());
            file.setUpdateUserId(CurrentUserHolder.get().getCompanyUserId());
            file.setUpdateTime(new Date());
            fileMapper.update(file,wrapper);


            //由于前端忘记传id过来，只能通过查找文件曲线救国
            LambdaQueryWrapper<DocFile> wrapper1 = new LambdaQueryWrapper<>();
            wrapper1.eq(DocFile::getName,file.getName());
            wrapper1.eq(DocFile::getFolderId,file.getFolderId());
            List<DocFile> tempFileList = fileMapper.selectList(wrapper1);
            DocFile tempFile = new DocFile();
            if(!CollectionUtils.isEmpty(tempFileList)){
                tempFile = tempFileList.get(0);
            }
            //给文件历史记录表添加记录
            DocFileHistory fileHistory = new DocFileHistory();
            if(fileDto.getId()==null){
                fileHistory.setFileId(tempFile.getId());
            }else{
                fileHistory.setFileId(file.getId());
            }
            fileHistory.setFileName(file.getName());
            fileHistory.setOperateUserId(CurrentUserHolder.get().getCompanyUserId());
            fileHistory.setOperateTime(new Date());
            fileHistory.setIsCreate((short)0);
            fileHistory.setContent(file.getContent());
            fileHistoryMapper.insert(fileHistory);
        }

    }




    /**
     * 分页查询员工
     * */
    @Override
    public PageResult<SysUserDTO> selectDocPersonnel(String keyword, Integer page, Integer pageSize) {
        LambdaQueryWrapper<SysUser> wrapper=new LambdaQueryWrapper<>();
        wrapper.eq(SysUser::getLastLoginCompanyId,CurrentUserHolder.get().getCompanyId());
        if(!StringUtils.isEmpty(keyword)){
            wrapper.like(SysUser::getUsername,keyword);
        }
        // 创建分页对象
        IPage<SysUser> ipage = new Page<>(page, pageSize);
        // 执行分页查询
        ipage=sysUserMapper.selectPage(ipage,wrapper);
        //获取当业的功能
        List<SysUser> docFiles = ipage.getRecords();
        if(!CollectionUtils.isEmpty(docFiles)){
            List<SysUserDTO> sysUserDTOS = BeanHelper.copyWithCollection(docFiles, SysUserDTO.class);
            return new PageResult<SysUserDTO>(ipage.getTotal(), ipage.getPages(), sysUserDTOS);
        }
        return new PageResult<SysUserDTO>(ipage.getTotal(), ipage.getPages(), null);
    }

    @Override
    public void updateStatu(Long personnelId, Short status) {
        SysUser sysUser = new SysUser();
        sysUser.setStatus(status);
        sysUser.setId(personnelId);
        sysUser.setLastLoginCompanyId(CurrentUserHolder.get().getCompanyId());
        sysUserMapper.updateById(sysUser);
    }
}
